/*
 *  The MIT License
 * 
 *  Copyright 2011 Jeremy Heng | Jaybles | Vxtherael.
 * 
 *  Permission is hereby granted, free of charge, to any person obtaining a copy
 *  of this software and associated documentation files (the "Software"), to deal
 *  in the Software without restriction, including without limitation the rights
 *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 *  copies of the Software, and to permit persons to whom the Software is
 *  furnished to do so, subject to the following conditions:
 * 
 *  The above copyright notice and this permission notice shall be included in
 *  all copies or substantial portions of the Software.
 * 
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 *  THE SOFTWARE.
 */
package jeremy.livestream;

import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import jeremy.livestream.exceptions.EmptyStreamNameRuntimeException;

/**
 *
 * @author Jeremy Heng | Jaybles | Vxtherael
 */
public class Stream {

    protected static int universalSalt = (int) (Math.random() * Integer.MAX_VALUE);
    protected static int modulo = (int) ((Math.random() * (Integer.MAX_VALUE - 100000)) + 100000);
    protected static Map<String, Integer> saltVals = new HashMap<String, Integer>();
    protected static Map<String, String> streamLookup = new HashMap<String, String>();
    protected static Map<Integer, Character> characterMap = new HashMap<Integer, Character>();

    static {
        initCharMap();
    }

    // There are better ways to mutate ASCII characters but I want to keep it html parsable and human readable.
    protected static void initCharMap() {
        if (characterMap.isEmpty()) {
            for (int i = 0; i < 52; i++) {
                if (i < 26) {
                    characterMap.put(i, (char) (i + 65));
                }
                else {
                    characterMap.put(i, (char) ((i - 26) + 97));
                }
            }
        }
    }

    public static String getHashedStreamName(String name) {
        String hashedString = null;
        if (name.isEmpty()) {
            throw new EmptyStreamNameRuntimeException();
        }
        if (!streamLookup.containsValue(name)) {
            char[] arr = name.toCharArray();
            if (!saltVals.containsKey(name)) {
                saltVals.put(name, (int) (Math.random() * Integer.MAX_VALUE));
            }
            int salt = (universalSalt * saltVals.get(name)) % modulo;
            salt = (salt < 0) ? salt + modulo : salt;
            for (int i = 0; i < arr.length; i++) {
                int temp = ((arr[i] * salt) % 52);
                arr[i] = characterMap.get((temp < 0) ? temp + 52 : temp);
            }
            hashedString = String.copyValueOf(arr);
            streamLookup.put(hashedString, name);
        }
        else {
            hashedString = streamLookup.get(name);
        }
        return hashedString;
    }

    public static void resetSaltValues() {
        universalSalt = (int) (Math.random() * Integer.MAX_VALUE);
        saltVals = new HashMap<String, Integer>();
    }

    public static String streamLookup(String hashed) {
        if (hashed.isEmpty()) {
            throw new EmptyStreamNameRuntimeException();
        }
        if (streamLookup.containsKey(hashed)) {
            return streamLookup.get(hashed);
        }
        else {
            return null;
        }
    }

}
